#ifndef BASECONTROLLER_H
#define BASECONTROLLER_H
#include "Eigen/Eigen"
#include "predef.h"
//#include <slaves/slavebase.h>
#include <memory>
#include <boost/shared_ptr.hpp>

class MainController;

class BaseController
{
public:
    BaseController(MainController *main_controller, const SlaveIndex slave_index=SlaveIndex::kNoneIndex);
    virtual ~BaseController();
    virtual ErrorCode Update()=0;

    virtual bool ParseUsrData(const u_char *buffer, const size_t buffer_len)=0;//only usr data, without frame header and crc
    virtual bool PackUsrData(u_char *buffer,size_t &buffer_len)=0;
    bool PackFrameData(u_char *buffer,size_t &buffer_len);
    inline void ClearTargetStatus(){ updated_attr_=0x00;}         //whole frame, with frame header and crc

    main_controller::RunningStatusType GetRunningStatus()const;
    main_controller::SocketConnectionStatusType GetConnectionStatus()const;

    inline char GetMasterDeviceIndex()const
    {
        if(master_device_index_==nullptr)
            return ErrorCode::kNoDeviceAllocated;
        else
            return *master_device_index_;
    }
    inline bool SetMasterDeviceIndex(char index)
    {
        if(master_device_index_==nullptr)
            return false;
        *master_device_index_=index;
        return true;
    }
    inline void AllocMasterDevice(std::atomic<char> *index){        master_device_index_=index;  }
    inline void RemoveMasterDevice(){     master_device_index_=nullptr;    }

    inline u_char GetSlaveTargetIndex()const {return slave_target_index_;}

//    inline bool IsStop()const{return stop_;}
//    inline void SetStop(const bool stop){stop_=stop;}

//    inline bool GetMasterEndPosition(Eigen::Vector3d &pos)const { return master_device_->GetEndPosition(pos);}
//    inline bool GetMasterEndLinearVel(Eigen::Vector3d &vel)const { return master_device_->GetEndLinearVel(vel);}
//    inline bool SetMasterForce(const Eigen::Vector3d &force)const { return master_device_->SetForce(force);}
//    inline bool SetMasterTorque(const Eigen::Vector3d &torque)const { return master_device_->SetTorque(torque);}
//    inline bool SetMasterForceAndTorque(const Eigen::Vector3d &force,Eigen::Vector3d &torque)const { return master_device_->SetForceAndTorque(force,torque);}

public:
    u_char updated_attr_;
    MainController *main_controller_;
protected:
    // main_controller::RunningStatusType status_;
    //bool master_ok_;
    //bool stop_;


    std::atomic<char> *master_device_index_;
    SlaveIndex slave_target_index_;

    u_char write_buffer_[kSocketBufferLen];
};
typedef boost::shared_ptr<BaseController> BaseControllerPtr;

#endif // BASECONTROLLER_H
